﻿using System.Linq;
using Microsoft.Xna.Framework;
using System.Collections.Generic;

namespace GameFlowManager.Screens
{
	public class ScreenManagerComponent : DrawableGameComponent, IScreenManager
	{
		#region Variables

		private List<GameScreen> _screens;

		#endregion

		#region Constructors

		public ScreenManagerComponent(Game game)
			: base(game)
		{
			_screens = new List<GameScreen>();

			game.Services.AddService<IScreenManager>(this);
		}

		#endregion

		#region Properties

		public GameScreen ActiveScreen
		{
			get
			{
				if (_screens.Count == 0)
				{
					return null;
				}
				return _screens.Last();
			}
		}

		#endregion

		#region Methods

		protected override void Dispose(bool disposing)
		{
			Game.Services.RemoveService<IScreenManager>();
			base.Dispose(disposing);
		}

		public override void Update(GameTime gameTime)
		{
			base.Update(gameTime);

			for (var index = 0; index < _screens.Count; index++)
			{
				_screens[index].Update(gameTime);

				if (_screens[index].GetState(gameTime) == ScreenState.Exit)
				{
					_screens[index].UnloadContent();
					_screens.RemoveAt(index);
					index--;
				}
			}
		}

		public override void Draw(GameTime gameTime)
		{
			base.Draw(gameTime);
			_screens.ForEach(x => x.Draw(gameTime));
		}

		/// <summary>
		/// Add a screen to the top of the stack.
		/// </summary>
		public void EnterScreen(GameScreen screen)
		{
			_screens.Add(screen);
			screen.Manager = this;
			screen.LoadContent();
		}

		/// <summary>
		/// Remove the screen at the top of the stack.
		/// </summary>
		public void LeaveScreen()
		{
			ActiveScreen.ExitScreen();
		}

		/// <summary>
		/// Replace the screen at the top of the stack with a new screen.
		/// </summary>
		/// <param name="screen"></param>
		public void SwitchScreens(GameScreen screen)
		{
			LeaveScreen();
			EnterScreen(screen);
		}

		#endregion
	}
}